/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package utn.tsb.tej.comunications.server;

import java.io.Serializable;
import utn.tsb.tej.comunications.GameData;
import utn.tsb.tej.world_logic.Color;
import utn.tsb.tej.world_logic.Player;
import csm.uttils.generics.Roster;

/**
 *
 * @author Carlos S. Moreno <CarlosS.Moreno@gmail.com>
 */
public class RoomGame implements Serializable{

    private static RoomGame roomGameInstance;

    private String roomName;
    private Roster<Player> players;
    private int maxPlayers;
    private Roster<Color> availableColors;

    public static RoomGame getInstance()
    {
        if (null == roomGameInstance) roomGameInstance = new RoomGame();
        return roomGameInstance;
    }

    public static void setInstance(RoomGame instance)
    {
        roomGameInstance = instance;
    }

    public RoomGame()
    {
        //int[] a = {1,2,3};
        roomName = "New TEJ Room Game";
        players = new Roster<Player>();
        availableColors = new Roster<Color>();
        {
            availableColors.addInOrder(new Color(Color.BLACK));
            availableColors.addInOrder(new Color(Color.BLUE));
            availableColors.addInOrder(new Color(Color.GREEN));
            availableColors.addInOrder(new Color(Color.RED));
            availableColors.addInOrder(new Color(Color.WHITE));
            availableColors.addInOrder(new Color(Color.YELLOW));
        }
        maxPlayers = 6;
    }

    /**
     * @return the roomName
     */
    public String getRoomName() {
        return roomName;
    }

    /**
     * @param aRoomName the roomName to set
     */
    public void setRoomName(String aRoomName) {
        roomName = aRoomName;
    }

    public synchronized  void addPlayer (Player player)
    {
        getPlayers().addLast(player);
    }

    public synchronized void removePlayer( Player player)
    {
        this.addColor(player.getColor());
        getPlayers().remove(player);
    }

    public synchronized void addColor (Color color)
    {
        if (availableColors.indexOf(color)!=-1) return;

        availableColors.addInOrder(color);
    }

    public synchronized void removeColor(Color color)
    {
       if (availableColors.indexOf(color)==-1) return;

       availableColors.remove(color);
    }

    public GameData getGameData()
    {
        GameData gData = new GameData(getRoomName());
        gData.setAvailablesColors(availableColors);
        gData.setPlayersCount(getPlayers().count());

        return gData;
    }

    /**
     * Is there any empty place in the room game for a new player?
     * @return False if the room is full.
     */
    public boolean anyEmptyPlace()
    {
        return getMaxPlayers() > getPlayers().count();
    }

    /**
     * @return the maxPlayers
     */
    public int getMaxPlayers() {
        return maxPlayers;
    }

    /**
     * @param maxPlayers the maxPlayers to set
     */
    public void setMaxPlayers(int maxPlayers) {
        this.maxPlayers = maxPlayers;
    }

    public synchronized Color getAnAvailableColor()
    {
        Color color = availableColors.getFirst();
        removeColor(color);
        return color;
    }

    public Roster<Color> getAllAvailableColors()
    {
        return availableColors;
    }

    /**
     * @return the players
     */
    public Roster<Player> getPlayers() {
        return players;
    }

    public boolean vaidateAddress(String address)
    {
        boolean result = false;
        players.startIterator();
        //While players is not at the end, and the result is still in false
        while (players.hasNext() && !result)
        {
            result = players.next().getAddress().compareToIgnoreCase(address) == 0;
        }
        return result;
    }

    public Player getPlayerByAddress(String address)
    {
        players.startIterator();
        //While players is not at the end
        while (players.hasNext())
        {
            Player aux = players.next();
            if (aux.getAddress().compareToIgnoreCase(address) == 0)
                return aux;
        }
        return null;
    }

    public boolean isColorAvailable(Color color)
    {
        boolean result = false;
        availableColors.startIterator();
        //While availableColor is not at the end, and the result is still in false
        while (availableColors.hasNext() && !result)
        {
            //If it founds the color in the Roster, the it is available
            result = availableColors.next().compareTo(color) == 0;
        }
        return result;
    }
}
